package com.my.study.limiter;

import com.my.study.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author: Carlos
 * @create: 2020/12/28 16:56
 */
@Component
@Slf4j
@ConditionalOnBean(RedissonClient.class)
public class RateLimiterFactory {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 本地对象存储
     */
    private volatile Map<String, RedisLimiter> redisPermitsMap = new ConcurrentHashMap<>(64);

    /**
     * 创建RedisLimiter
     *
     * @param key  redis key
     * @param permitsPerSecond  每秒产生的令牌数
     * @param maxBurstSeconds    最大存储多少秒的令牌
     * @return
     */
    public RedisLimiter build(String key, Double permitsPerSecond, Integer maxBurstSeconds) {
        if (!redisPermitsMap.containsKey(key)) {
            synchronized (this) {
                if (!redisPermitsMap.containsKey(key)) {
                    String lockKey = "DISTRIBUTED_LOCK:" + key;
                    RLock lock = redissonClient.getLock(lockKey);
                    redisPermitsMap.put(key, new RedisLimiter(key, permitsPerSecond, maxBurstSeconds, lock, redisUtil));
                }
            }
        }
        return redisPermitsMap.get(key);
    }
}
